/**
* 
* GUI: Graphical window console
* Copyright (c) 2009 Ecole Centrale de Nantes IRCCyN  
* Classe: JConsole.java 
* see <a href="{@docRoot}/">for more information</a>
* 
* @author: Urunuela Richard
* @version 3.2
*/
package programme.GUI;

import programme.programme;

import storm.ISimulationKernel;
import storm.Version;
import stormIO.XmlFactory;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.ProgressMonitor;
import javax.swing.SwingUtilities;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.xml.parsers.ParserConfigurationException;

import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;



/**
 * 
 * @author richard
 *
 */
public class JConsole extends JTextPane implements KeyListener {
    String prompt="##> ";
	int idx;
	int ligne=0;
	String commande;
	private programme envt;
	CHistory History;
	int oldposition=0;
	public StringBuffer message;
//	private String version="Version 3.3 - B";
	boolean predcommande=true;
	boolean shift = false;
	boolean controle = false;
    private GUIProgramme refOwner;

	
/**
 * Commands historic 
 * @author richard
 *
 */
	private class CHistory{
		int pointer=0;
		Vector commande;
		
		int limite = 10;
		/**
		 * 
		 */
		public CHistory(){
			commande = new Vector();
			
		}
		/**
		 * 
		 * @return string of pred commands
		 */
		public String getPred(){
			if (this.commande.size()==0) return "";
			pointer = pointer - 1;
			pointer = (pointer < 0) ? 0: pointer;  
			
			String res = (String)commande.get(pointer);
			
			return res;
			
		}
		/**
		 * 
		 * @param str new command to save
		 */
		private void addString(String str){
			commande.add(str);
			if (commande.size()> limite) {
				commande.remove(0);
			}
			
		}
		/**
		 * 
		 */
		private void  reset(){
			this.pointer = commande.size();
		}
		/**
		 * 
		 * @return
		 */
		private String getNext() {
			String res;
			pointer = pointer + 1;
			if (commande.size() == 0  ) return "";
			if (pointer == (commande.size())){
				res  = "";
				pointer = pointer -1;
				return res;
			}
			else{
				res =  (String)commande.get(pointer);
				
				return res;
				
			}
		
			
		}
	}

/**
 * small warning in console	
 * @author richard
 *
 */
	private class warningButton extends JLabel{
		public warningButton(){
			super();
			ClassLoader cl = this.getClass().getClassLoader();
		    java.net.URL url = cl.getResource("images/warning.gif");
		    ImageIcon icon = new ImageIcon(url,"");
		    this.setIcon(icon);
		}
	}
	/**
	 * To finish
	 * @author richard
	 *
	 */
	private class okButton extends JLabel{
		public okButton(){
			super();
			ClassLoader cl = this.getClass().getClassLoader();
		    java.net.URL url = cl.getResource("images/warning.gif");
		     
		    ImageIcon icon = new ImageIcon(url,"");
		    this.setIcon(icon);
		}
	}
	/**
	 * 
	 * @return
	 */
	private programme getEnvt() {
		return envt;
	}
	/**
	 * 
	 * @param envt
	 */
	private void setEnvt(programme envt) {
		this.envt = envt;
	}
	/**
	 * 
	 * @param c
	 * @param s
	 */
	 public void append(Color c, String s) { 
		 // better implementation--uses
         // StyleContext
		 StyleContext sc = StyleContext.getDefaultStyleContext();
		 AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
				 StyleConstants.Foreground, c);

		 int len = getDocument().getLength(); 
		 // Verifier que la console n'explose pas 
		 //---
		if (len > 10000)
			try {
				this.setText( this.getText(5000, len-5000) );
			} catch (BadLocationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			len = getDocument().getLength(); 
		 /**
		  * 
		  */
		 
		 setCaretPosition(len); // place caret at the end (with no selection)
		setCharacterAttributes(aset, false);
		 replaceSelection(s); // there is no selection, so inserts at caret
		 
	 }
	 /**
	  * 
	  * @param token
	  */
   public void afficheMemory(StringTokenizer token){
	   DecimalFormat df = new DecimalFormat("0.00") ;
	   long totalMemory = Runtime.getRuntime().totalMemory(); 
	   long  freeMemory = Runtime.getRuntime().freeMemory();
	   long  MaxMemory  = Runtime.getRuntime().maxMemory();
	   this.append(Color.blue,"\n Memory usage in MB \n Total memory " + df.format(totalMemory/1000000F) +  "\n Free memory "+ df.format(freeMemory/1000000F) +"\n Max memory "+   df.format(MaxMemory/1000000F)  + "\n" );
	   this.append(Color.black,"\n##> ");
    }
   /**
    * 
    * @param S
    */
	public void afficheError(String S){    	    	    		
		this.insertComponent(new warningButton());
		this.append(Color.red, S + "\n");
		this.append(Color.black,"##> ");
	}
/**
 * 
 * @param string
 * @param i
 * @param j
 */
	public JConsole(String string, int i, int j) {
		super();
		this.message = new StringBuffer("");
		this.addKeyListener(this);
		this.setText(this.prompt);
		History = new CHistory();
		setFocusTraversalKeysEnabled(false);
	}
	/**
	 * clear console
	 * @param token
	 */
	public void setClear(StringTokenizer token){
		 this.setText("##> ");
	}
	/**
	 * Prototype
	 * @param token
	 */
	private void setLightExec(StringTokenizer token){
		this.envt.setLightExec(true);
		this.setExec(token);
	}
	/***
	 * Load and exec script
	 */
	public void loadexec(StringTokenizer token){
		if(token.countTokens() == 0 ) {
			this.afficheError("[900] usage exec <filename>");
			return;
		}
		String Filename = token.nextToken();
		if (!this.envt.processL(Filename,this)) {
			this.afficheError("[711] Error parsing file ");
			return;
		}
		
	}
	
	/**
	 * Exec simulation
	 * @param token
	 */
	public void setExec(StringTokenizer token){
		this.envt.setLightExec(false); 
		if(token.countTokens() == 0 ) {
			this.afficheError("[100] usage exec <filename>");
			return;
		}
		 String Filename = token.nextToken();
		 /**
		  * Close all window before exec
		  */
		if (this.envt.isAlive()) {
			this.envt.closeall(this);
			this.envt.freeAll();
		}
		this.append(Color.black,"Load file \n");
		this.envt.addFileNameSimu(Filename);
		long startTime = System.nanoTime();
				
		try {
			this.envt.createSimu(this);

		} catch (SAXException e) {
			
			
			/**
			* see <a href="{@docRoot}/documentation/errot.html">Trace for more information</a>
			 * 
			 */
			/**
			 * error 210 sax error 
			 */
			if (e instanceof SAXParseException){
				SAXParseException ee = (SAXParseException) e;
				String res = "[210]  Ligne "+ee.getLineNumber()+", colonne "+ee.getColumnNumber()+"\n" + 
						 e.getMessage();
				this.afficheError(res);
				return;
			}
			else {
				String res = ("[210] " + e.getMessage());
				this.afficheError(res);
				return;
			}
			/**
			 * error 220 Basic IO error (eg file not found 
			 */
		} catch (IOException e) {
			String res =("[220] " + e.getMessage());
			this.afficheError(res);
			return;
		}
		/**
		 * error 230 Erro Parser (XMl not correct)
		 */
		catch (ParserConfigurationException e) {
			String res = ("[230] " + e.getMessage());
			this.afficheError(res);
			return;
		} 
		/**
		 * error 320 reflect method not exist
		 */
		catch (NoSuchMethodException e) {
			String res = ("[320] " + e.getMessage());
			this.afficheError(res);
		}
		/**
		 * error 330 reflect method not exist
		 */
		catch (InstantiationException e) {
			String res = ("[330] " + e.getMessage());
			this.afficheError(res);
		}
		/**
		 * error 340 try to acces private member
		 */
		catch (IllegalAccessException e) {
			String res = ("[340] " + e.getMessage());
			this.afficheError(res);
		}
		/**
		 * error 350 
		 */
		catch (InvocationTargetException e) {
			String res = ("[350] " + e.getMessage() + "" + e );
			this.afficheError(res);
		}
		/**
		 * Error 360 error with attribut not used (eg use quantum but not use in XML file -> q=0 :( ) 
		 */
		catch (Throwable e) {
			StringWriter sw = new StringWriter();
		    PrintWriter pw = new PrintWriter(sw);
		    e.printStackTrace(pw);

			String res = ("[360]  :  \n" + sw.toString() );
			this.afficheError(res);
		}
		long stopTime = System.nanoTime();
		this.append(Color.blue,"--> "+ (int)((stopTime - startTime)/1000.0/1000.0) + " ms");
		this.append(Color.black,"\n##> ");
		
	}	
	/**
	 * help screen 
	 * @param token
	 */
	public void setHelp(StringTokenizer token){
	 	this.message = new StringBuffer ("\n");
		
		this.append(Color.blue,"\n| ------------------- |" + "\n");
	 	this.append(Color.blue,"| Commands |");
		for(int i=0; i < this.listeCommandes.length ; i = i+6){
			this.message.append(" - " + listeCommandes[i]+" (" +listeCommandes[i+1]+ ") " +listeCommandes[i+2]+" : "  +   listeCommandes[i+3]+ "\n");
		}
	 	  this.append(Color.blue,this.message.toString());;
	 	 this.append(Color.blue,"| ------------------- |" + "\n");
	 	 this.append(Color.blue,"| Separate commands with ; |" + "\n");
	 	 
	 	this.append(Color.blue,"| ------------------- |" + "\n");
	 	this.append(Color.blue,"| shortcuts  |" + "\n");
	 	this.append(Color.blue,"| ------------------- |" + "\n");
	 	for(int i=1; i < this.listeKeyCut.length ; i = i+5){
	 		this.append(Color.blue,listeKeyCut[i]+" \n" );
	 	}
	 	

	 	 this.append(Color.black,"##> ");
	
	}
	/**
	 * context screen
	 * @param token
	 */
	public void setContext(StringTokenizer token){
	 this.envt.showctx(this);
	 this.append(Color.black,this.message + "\n" +"##> ");
	}
	/**
	 * Plot all gantt diagram 
	 * @param token
	 */
	public void plotall(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		 this.envt.showGrapTemp();
	}
	/**
	 * Quit program
	 * @param token
	 */
	public void quit(StringTokenizer token){
		 	 this.envt.quit();
	}
	/**
	 * Calcl power for a processor
	 * @param token
	 */
	public void calcpower(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[120] usage : calcpower (cp) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (this.envt.calcPower(num,this)){
	 		 this.append(Color.blue, this.message+"");
	 		 this.append(Color.black, "\n##> ");
	 	 }
	 	 else 
	 		this.afficheError("[121]  Id incorrect");	
	 	 //this.setText(this.getText()+this.message + "\n##> ");
	}
	/**
	 * Plot power for a processor
	 * @param token
	 */
	public void plotpower(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[100] usage : plotpower (pp) <c>");
			return;
		}
	     String num =  token.nextToken();
	     
	 	 if (!(this.envt.drawPowerGraph(num)) )
	 		this.afficheError("[101]  Id incorrect");	;
	}
	/**
	 * Plot dvfs for a processor
	 * @param token
	 */
	public void plotdvfs(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[130] usage : plotdvfs  (pd) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	if(! this.envt.drawDVSGraph(num)){
	 		this.afficheError("[131] id incorrect");
	 	}
	 			
	}
	/**
	 * Plot load for a processor 
	 * @param token
	 */
	public void plotload(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[140] usage : plotload (pl) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (!(this.envt.drawLoadGraph(num))) 
	 		this.afficheError("[141] Id incorrect ");
	}
	/***
	 * plot instant load
	 */
	public void plotpload(StringTokenizer token){
		
	}

	
	/**
	 * PlotAET for a task
	 */
	public void plotaet(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[180] usage : plotaet (pt) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (! this.envt.drawAETGraph(num)){
	 		this.afficheError("[181] Id incorrect");
	 	 }
	}
	/**
	 * Plot ret for a task 
	 * @param token
	 */
	public void plotret(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[150] usage : plotret (pt) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (! this.envt.drawRETGraph(num)){
	 		this.afficheError("[151] Id incorrect");
	 	 }
	 		 
	}
	/**
	 * Response time
	 */
	public void rtime(StringTokenizer token){
	 	 
			if (!(this.envt.isAlive())) {
				this.afficheError("[110] No simulation");
				return;
			}
			if(token.countTokens() == 0 ) {
				this.afficheError("[1150] usage : rtime  T)");
				return;
			}
		     String num =  token.nextToken();
		 	 if (this.envt.getResponseTime(num,this)){
		 		 this.append(Color.blue, this.message+"");
		 		 this.append(Color.black, "\n##> ");
		 	 }
		 	 else 
		 		this.afficheError("[121]  Id incorrect");	
	 	 
	} 		 

	/**
	 * Display a gantt for a processor or a task 
	 */
	public void gantt(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[600] usage : gantt (gtt) <i>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (!this.envt.drawGantt(num)){
	 		this.afficheError("[661] Id incorrect");
	 	 }
		
	}
	/**
	 * plot final ret for a task
	 * @param token
	 */
	/*public void plotfret(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[100] usage : plotfret (pft) <c>");
			return;
		}
	     String num =  token.nextToken();
	 	 if (!this.envt.drawFRETGraph(num)){
	 		this.afficheError("[161] Id incorrect");
	 	 }
	}*/
	/**
	 * Close all windows except console
	 * @param token
	 */
	public void closeall(StringTokenizer token){
		  this.envt.closeall(this);
	}
	/**
	 * 
	 * @param token
	 */
	public void setpos(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() <=1 ) {
			this.afficheError("[100] usage : setpos (sp) <g> <n> [z]");
			return;
		}
		 String num =  token.nextToken();
				 String pos = token.nextToken();
				 if (token.countTokens() > 0) {
					 String z = token.nextToken();
					 this.envt.setPos(num,pos,z);
				 }
				 else {
					 this.envt.setPos(num,pos);
				 }
	}
	/**
	 * change zoom for a gantt or xY windows
	 * @param token
	 */
	public void setzoom(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() <=2  ) {
			this.afficheError("[100] usage : setzoom  (sz) <g> <d> <f>");
			return;
		}
		String num = token.nextToken();
		if (token.countTokens() > 0) {
		 String X1 =  token.nextToken();
		 String X2  = token.nextToken();
		 this.envt.setZoom(num,X1,X2);
		}
		else {
			this.envt.setZoomAll(num);
		}
	}
	/**
	 * Show kernel internal message 
	 * @param token
	 */
	public void showmess(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() == 0 ) {
			this.afficheError("[100] usage : showmess (sm) <d>");
			return;
		}
		
		 String num =  token.nextToken();
		 
		 this.envt.showmess(num);
	}
	/**
	 * show dvfs message
	 * @param token
	 */
	public void showdvs(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() <=1  ) {
			this.afficheError("[100] usage : showdvfs (sd) <d> <f>");
			return;
		}
		
		String deb =  token.nextToken();
		String fin =  token.nextToken();
		 this.envt.showdvs(deb,fin);
		 
	}
	/**
	 * display version 
	 */
	public void affVersion(StringTokenizer token){
		this.append(Color.blue, Version.version);
		this.append(Color.black,"\n##> ");
	}
	/**
	 * Show penality application 
	 * @param token
	 */
	public void showpenality(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() <=1  ) {
			this.afficheError("[100] usage : showpoenality  (spy) <d> <f>");
			return;
		}
		
		String deb =  token.nextToken();
		String fin =  token.nextToken();
		 this.envt.showpenality(deb,fin);
		 
	}
	/**
	 * Windows information screen 
	 * @param token
	 */
	public void windowsinfo(StringTokenizer token){
		  this.envt.showInfoGraph(this);
		  this.append(Color.black,this.message + "\n##> ");
	}
	/**
	 * Window task grapg precedente
	 * @param token
	 */
	public void graphdata(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		  this.envt.showDataGraph(this);
	}
	/**
	 * Create window explorer 
	 * @param token
	 */
	public void launchExplorer(StringTokenizer token){
		this.envt.showExplorer(this);
	}
	/**
	 * Create txt|pdf|GUI report
	 * @param token
	 */
	public void report(StringTokenizer token){
		if (!(this.envt.isAlive())) {
			this.afficheError("[110] No simulation");
			return;
		}
		if(token.countTokens() <=1  ) {
			this.afficheError("[100] usage : report filename output ");
			return;
		}
		String f=  token.nextToken();		
		String out=  token.nextToken();

		if (!this.envt.processReport(this,f,out)) {
			this.afficheError("[711] Error parsing file ");
			return;
		}
	}
	/**
	 * Close a Window
	 * @param token
	 */
	public void closeWindow (StringTokenizer token){
		if(token.countTokens() !=1  ) {
			this.afficheError("[101] usage : close (cl) <g> ");
			return;
		}
		 String num =  token.nextToken();
		 this.envt.CloseWindow(num);
	}
	/**
	 * save window in JPEG file
	 * @param token
	 */
	public void printjpeg(StringTokenizer token){
		
		if(token.countTokens() <=1  ) {
			this.afficheError("[100] usage : print (pr) <g> <filename>");
			return;
		}
		 String num =  token.nextToken();
		 String Filename = token.nextToken();
		 
		 this.envt.saveFrameAsJepg(num,Filename);
	}
	/**
	 * Xml set System ENTITY VALUE in a file
	 */
public void xmlSetEntity(StringTokenizer token){
		
		if(token.countTokens() < 4  ) {
			this.afficheError("[100] usage : xmlSetEntity  <filename source > <filename destination>  <Entity name>  <value>");
			return;
		}
		String file=  token.nextToken();
		String filename = token.nextToken();
	String entity=  token.nextToken();
	String newValue=  token.nextToken();
	 try {
		stormIO.XmlEntity.changeEntityValue(entity, newValue, file, filename);
	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		
}
	/**
	 * Xml set attribut in a file
	 */
	public void xmlSet(StringTokenizer token){
		
		if(token.countTokens() < 5  ) {
			this.afficheError("[100] usage : xmlSet <filename source > <filename destination>  <id> <atribut> <value>");
			return;
		}
		
		 String Filename = token.nextToken();
		 String Filenamed = token.nextToken();
		 String id= token.nextToken();
		String attribut = token.nextToken();
		String value = token.nextToken();
		
			XmlFactory factory= new XmlFactory(Filename);
			try {
				if (! factory.proceed(Filenamed,id,attribut,value)) this.afficheError("[NA] xml no value modify");
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				this.afficheError(e.toString());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				this.afficheError(e.toString());
			}
		 //this.envt.saveFrameAsJepg(num,Filename);
	}
	
	/**
	 * Short Key  
	 * Id ; information ; need control ; need shift ; KEY
	 */
	private Object listeKeyCut[]={
		// control Shift	
		"1","<control> q: Close window",Boolean.TRUE,Boolean.FALSE,new Integer(KeyEvent.VK_Q),	
		"2","<shift> tab:  next window",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_TAB),
		
		"4","<shift> end: reset current window",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_END),
		"5","<shift> home: reset all window",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_HOME),
		"6","page_up: move graph on right",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_PAGE_UP),
		"7","page_down: move graph on left",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_PAGE_DOWN),
		"6","<shift>right: move graph on right",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_RIGHT),
		"7","<shift>left: move graph on left",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_LEFT),
		"8","F12: reorganize window save Position",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F12),
		"9","F1:  reorganize window restore Position",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F1),
		"10","F2: reorganize window Group",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F2),
		"11","F3: reorganize window all space",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F3),
		"12","F4: reorganize window by theme console mid",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F4),
		"13","<shift>up: Zoom in",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_UP),
		"14","<shift>down: Zoom out",Boolean.FALSE,Boolean.TRUE,new Integer(KeyEvent.VK_DOWN),
		"15","down: history pred",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_DOWN),
		"16","up: history next",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_UP),
		"17","F5: show/hide explorer",Boolean.FALSE,Boolean.FALSE,new Integer(KeyEvent.VK_F5),
		 
	};
	/**
	 * List of diffent command command and funtion 
	 * command; short command; argument ; information ; null ; function to call 
	 */
	private String listeCommandes[] ={
			"clear","cls","","clear commande","","setClear",
			"exec","ex"," <filename>","use filename","","setExec",
			
			
			//"lexec","lex"," <filename>","light and fast exec","","setLightExec",
			"load","ld"," <filename>","use filename for script","","loadexec",
			"help","?","","help ","","setHelp",
			"context","ctx","","show context simulation ","","setContext",
			"plotall","pa","","plot all scheduling graph ","","plotall",
			"exit","xt","","exit program ","","quit",
			"calcpower","cp","<c>"," calculate cpu power consumption for processor c,c is the id known with ctx","","calcpower",
			"plotpower","pp","<c>","plot cpu power consumption for processor c,c is the id known with ctx" ,"", "plotpower",
			"plotdvfs","pd","<c>","plot cpu dvfs for processor c,c is the id  known with ctx ","","plotdvfs",
			"plotload","pl","<c>","plot cpu load for processor c,c is the id known with ctx ","","plotload",
			"plotret","pt","<t>","plot cpu ret evolution for task t,t is the id  known with ctx ","","plotret",
			"plotaet","paet","<t>","plot AET  evolution for task t,t is the id  known with ctx ","","plotaet",
			"plotpload","plp","","plot global load  evolution  ","","plotpload",
		//	"plotfret","p","<t>","plot cpu fixe ret evolution for task t,t is known with ctx ","","plotfret",
			"closeall","cla","","close all windows ","","closeall",
			"setpos","sp","<g> <n>","change offset for gantt graph g to value n ","","setpos", //dans storm on a 3 param -- le zoom
			"setpos","sp","<g> <n> <z>","change offset for gantt graph g to value n with zoom z(0|1|2|3)","","setpos", //dans storm on a 3 param -- le zoom
			"setzoom","sz","<g> <d> <f>","setzoom for axis graph g between d and f","","setzoom",
			"setzoom","sz","<g>","reset zoom for axis graph g","","setzoom",
			"showmess","sm","<d>","show kernel message for date d","","showmess",
			"showdvfs","sd","<d> <f>","show dvfs commands between date d and f","","showdvs",
			"showpenality","spy","<d> <f>","show penality  commands between date d and f","","showpenality",
			"windowsinfo","wi","","show window information and numero","","windowsinfo",
			"taskdata","td","","show task data graph","","graphdata",
			"print","pr","<g> <filename>","save graph <g>(see numero with wi command) in  <filename>.jpeg ","","printjpeg",
			"memory","mem","","show memory information ","","afficheMemory",
			"explorer","exp","","explorer","","launchExplorer",
			"gantt","gtt","<i>","create gantt for item i, i is the id  known with ctx ","","gantt",
			//getResponseTime
			"rtime","rti","<t>",", get response time  for task T (min max average variance)","","rtime",
			"report","rep","","create report","","report",
			"version","vr","","this version","","affVersion",
			"xmlSet","xs","","set xml attribut in a file","","xmlSet",
			"xmlSetEntity","xe","","set xml Entity value  in a file","","xmlSetEntity",
	
			"close","cl","<g>","close Window g (cf wi)","","closeWindow"
			};

/**
 * which function for which command
 * @param commande
 * @param token
 * @return
 */

	private boolean setCommande(String commande,StringTokenizer token){
		boolean res = false;
		
		
		for (int i =0; i < listeCommandes.length; i = i +6 ){
			if((commande.contentEquals(listeCommandes[i])) ||(commande.contentEquals(listeCommandes[i+1]))){
				Class c;
				try {
					c = Class.forName("programme.GUI.JConsole");
					Class partypes[] = new Class[1];
					
					 partypes[0] = StringTokenizer.class;

					Method m = c.getMethod(listeCommandes[i+5],partypes);
					Object arglist[] = new Object[1];
					
					arglist[0] = token;
					res = true ;

					m.invoke(this,arglist);
					return res;
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			
			}
		}
		return res;
		
	}
/**
 * Parse command string
 * @param com
 */
	private void parse(String com){
		com= com.trim();
		if(com.length()<=1){
			 return;
		 } 
		StringTokenizer listecommande = new StringTokenizer(com,";");
		while(listecommande.countTokens()>0){
			StringTokenizer tokenizer = new StringTokenizer(listecommande.nextToken(),",() \" \'");
			if (tokenizer.countTokens() == 0)return; 
			//	taille commande
			String commande=tokenizer.nextToken();
			if (this.setCommande(commande, tokenizer)) {
				History.addString(com.trim());
			}
			else {
				this.afficheError("[Unknown command] " + commande );
				return;
			}
		}
	
	}
	/**
	 * 
	 * 
	 */
	public void keyPressed(KeyEvent e) {
		String commande;
		
		
		int n=0;
		/**
		 * get value of commande 
		 */
		float value = this.getValueKeyCut(e);
	
		/**
		 * Controle key
		 */
		
		if (e.getKeyCode() == KeyEvent.VK_SHIFT){
			shift = true;
		}
		if (e.getKeyCode() == KeyEvent.VK_CONTROL){
		//	e.consume();
			controle = true;
		}
		/**
		 *Commande
		 *
		 */
		
		/**
		 *Ignore 	and Consume 
		 */
		if (value == -1) {

			e.consume();
		}
		/**
		 *  Ignore
		 */

		if (value == 0) {
		 	
		}
		/**
		 *  Close window		
		 */
		if (value==1) {
			this.closeSelect();
		}
		/**
		 * Set focus window
		 */
		if (value==2) {
			this.setTabFocus();
			e.consume();
		}
		/**
		 * reset current window
		 */
		if (value==4) {
			this.viewreset();
			e.consume();
		}
		/**
		 * reset all window
		 */
		if (value==5) {
			this.resetViewAll(); 
			e.consume();
		}
		/**
		 *  move graph on right
		 */
		if (value==6) {
			this.moveRightView();
			
			e.consume();
		}
		/**
		 *  move graph on left
		 */
		if (value==7) {
			this.moveLeftView();
			
			e.consume();
		}
		/**
		 *  reorganize window save Position
		 */
		if (value==8) {
			this.envt.reArrangeWindow(0);
			e.consume();
		}
		/**
		 * reorganize window restore Position
		 */
		if (value==9) {
			this.envt.reArrangeWindow(1);
			e.consume();
		}
		/**
		 * reorganize window Group
		 */
		if (value==10) {
			this.envt.reArrangeWindow(2);
			e.consume();
		}
		/**
		 * reorganize window all space
		 */
		if (value==11) {
			this.envt.reArrangeWindow(3);
			e.consume();
		}
		/**
		 * eorganize window by theme console mid
		 */
		if (value==12) {
			this.envt.reArrangeWindow(4);
			e.consume();
		}
		/**
		 * Zoom in		
		 */
		if (value==13) {
			this.doZoom(1);
			e.consume();
		}
		/**
		 * Zoom out
		 */
		if (value==14) {
			this.doZoom(0);
			e.consume();
		}
		/**
		 * show/hide explorer
		 */
		if (value==17) {
			this.launchExplorer(null);
			e.consume();
		}
		/**
		 * 	history pred	
		 */
		if (value==15) {
			
				this.select(this.oldposition, this.getCaretPosition());
				this.replaceSelection("");
				this.append(Color.black, History.getNext());
				e.consume();
			
		
		}
		/**
		 * history next
		 */
		if (value==16) {
			e.consume();
			if (predcommande) {
			History.reset();
			this.oldposition = this.getCaretPosition();
			this.append(Color.black, History.getPred());
			predcommande= false;
			return;
			
			}
			else{
				this.select(this.oldposition, this.getCaretPosition());
				this.replaceSelection("");
				this.append(Color.black, History.getPred());
				return;
			}
			
		}
		/**
		 * Other Keycode to ignore 
		 */
		if(e.getKeyCode() == KeyEvent.VK_DELETE || e.getKeyCode() == KeyEvent.VK_BACK_SPACE)
	    {
			if(this.getText().charAt(this.getCaretPosition() - 2) == '>')
	        {
				e.consume();
	        }
	    }
	    if(e.getKeyCode() == KeyEvent.VK_ENTER)
	    {
	    	int startPos = this.getText().lastIndexOf("##> ") + 3;
	        commande = this.getText().substring(startPos);
	       this.append(Color.black, "\n##> ");
	       e.consume();
	       parse(commande);
	    }
	         this.requestFocus();
	         predcommande= true;
	         
	}

	 /**
	  * 
	  * MAke a zoom 
	  * @param i
	  */
	public void doZoom(int i) {
		
		if (this.envt.isAlive()){
			InternalFrame crt = this.envt.getSelectFrame();
			if(crt != null) {
				crt.doZoom(i);
			}
			}
		
	}
	/**
	 * calculate id for short key 
	 * @param e
	 * @return
	 */
	private float getValueKeyCut(KeyEvent e) {

		for (int i=0; i < this.listeKeyCut.length ; i= i + 5) {
				if (e.getKeyCode() == ((Integer)(this.listeKeyCut[i+4])).intValue() ) {
					if (this.controle != (((Boolean)this.listeKeyCut[i+2]))) continue;
					if (this.shift != (((Boolean)this.listeKeyCut[i+3]))) continue;
					else return (new Float((String)(this.listeKeyCut[i]))).floatValue();
				}
		}
		return 0;
	}
	/**
	 * Close select window
	 */
	public void closeSelect() {
		if (this.envt.isAlive()){
			InternalFrame crt = this.envt.getSelectFrame();
			if (crt != null){
				this.envt.removeFrame(crt);
			}
		}
	}
	/**
	 * change focus beetween window
	 */
	public void setTabFocus() {
		boolean select = false;
		if (this.envt.isAlive()){
			ArrayList liste = this.envt.getListeFrame();
			Iterator i =   liste.iterator();
			while (i.hasNext()){
				InternalFrame crt = (InternalFrame) i.next();
				if (crt.isSelected()){
					if (i.hasNext()) {
						crt.setSelected(false);
						crt = (InternalFrame) i.next();
						crt.setSelected(true);
						crt.toFront();
						select =true;
					}
					else{
						crt.setSelected(false);
						crt = (InternalFrame) liste.get(0);
						crt.setSelected(true);
						crt.toFront();
						select=true;
					}
				}
			}
			if (!select){
				InternalFrame crt = (InternalFrame) liste.get(0);
				crt.setSelected(true);
				crt.toFront();
			}
		}
		
	}
	/**
	 * Reset Zoom and pos
	 */
	public void viewreset() {
		if (this.envt.isAlive()){
			InternalFrame crt = this.envt.getSelectFrame();
			if(crt != null) {
				crt.moveView(0);
			}
		}
	}
	/**
	 * Graph move axe to left
	 */
	public void moveLeftViewAll() {
		if (this.envt.isAlive()){
			ArrayList liste = this.envt.getListeFrame();
			Iterator i =  liste.iterator();
			while (i.hasNext()){
				InternalFrame crt = (InternalFrame) i.next();
				crt.moveView(1);
			}
		}
	}
	/**
	 * reset zoom for all window
	 */
	public void resetViewAll() {
		if (this.envt.isAlive()){
			ArrayList liste = this.envt.getListeFrame();
			Iterator i =  liste.iterator();
			while (i.hasNext()){
				InternalFrame crt = (InternalFrame) i.next();
				crt.moveView(0);
			}
		}
	}
	/**
	 * Graph move axe to right for all graph
	 */
	public void moveRightViewAll() {
		if (this.envt.isAlive()){
			ArrayList liste = this.envt.getListeFrame();
			Iterator i =  liste.iterator();
			while (i.hasNext()){
				InternalFrame crt = (InternalFrame) i.next();
				crt.moveView(2);
			}
		}
	}
	/**
	 * Graph move axe to left
	 */
	public void moveLeftView() {
		if (this.envt.isAlive()){
			InternalFrame crt = this.envt.getSelectFrame();
			if(crt != null) {
				crt.moveView(1);
			}
		}
	}
	/**
	 * Graph move axe to right
	 */
	public void moveRightView() {
		if (this.envt.isAlive()){
			InternalFrame crt = this.envt.getSelectFrame();
			if(crt != null) {
				crt.moveView(2);
			}
		}

	}
	/**
	 * release key
	 */
	public void keyReleased(KeyEvent e) {
				
		if (e.getKeyCode() == KeyEvent.VK_SHIFT){
			shift = false;
		}
		if (e.getKeyCode() == KeyEvent.VK_CONTROL){
			controle = false;
		}
		if (e.getKeyCode() == KeyEvent.VK_TAB){
		}
		this.requestFocus();
	
	}

	 /**
	  * 
	  * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
	  */
	public void keyTyped(KeyEvent e) {
		
		
	}
	
	/**
	 * 
	 * @param envt2
	 */
	public void setprogramme(programme envt2) {
		this.envt = envt2;
	}
	/**
	 * 
	 * @param programme
	 */
	public void setFrame(GUIProgramme programme) {
		this.refOwner = programme;
	}
	/**
	 * 
	 * @return
	 */
	public  ISimulationKernel getKernel(){
		return this.envt.getMonKL();
	}
	public void execCommande(String myLine) {
		this.parse(myLine);
		// TODO Auto-generated method stub
		
	}

}

